//
// Copyright (c) 2005 BroadVision, Inc. All rights reserved.
//
// This software is copyrighted.  Under the copyright laws, this software
// may not be copied, in whole or in part, without prior written consent
// of BroadVision, Inc. or its assignees.  This software is provided under
// the terms of a license between BroadVision and the recipient, and its
// use is subject to the terms of that license.
//
// This software may be protected by one or more U.S. and International
// patents.  Certain applications of BroadVision One-To-One software are
// covered by U.S. patent 5,710,887.
//
// TRADEMARKS: BroadVision and BroadVision One-To-One are registered
// trademarks of BroadVision, Inc., in the United States and the European
// Community, and are trademarks of BroadVision, Inc., in other
// countries.  The BroadVision logo, is a trademark of BroadVision, Inc.,
// in the United States and other countries. Additionally, IONA and Orbix
// are trademarks of IONA Technologies, Ltd.  RSA, MD5, and RC2 are
// trademarks of RSA Data Security, Inc.
//

package com.broadvision.manage.common.tools.action.group;

import java.util.*;
import java.security.Principal;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.Globals;
import org.apache.commons.beanutils.PropertyUtils;

import com.broadvision.web.util.ViewDynaBean;
import com.broadvision.system.accesscontrol.client.*;
import com.broadvision.data.client.DataManager;
import com.broadvision.visitor.client.VisitorManager;
import com.broadvision.visitor.client.Visitor;
import com.broadvision.visitor.client.VisitorGroupManager;
import com.broadvision.visitor.utils.GroupContextParser;
import com.broadvision.visitor.interfaces.VisitorGroup;

import com.broadvision.manage.common.tools.user.UserSearch;
import com.broadvision.manage.common.tools.user.UserProfile;
import com.broadvision.manage.tools.action.BaseAction;
import com.broadvision.license2.*;
import com.broadvision.manage.common.tools.action.user.UserUtils;
import com.broadvision.portal.services.*;

/**
 * Searches users or subgroups.
 */
public class GroupSearchAction extends BaseAction {

  public static final String VIEW_BEAN_NAME = "mtGroupSearchView";
  public static final String DTO_BEAN_NAME  = "mtGroupDTO";

  public static final String DTO_MEMBER_BEAN_NAME  = "mtGroupMemberDTO";

  public static final VisitorManager visitorMgr = new VisitorManager();

  /**
   * Implements the action for browsing a group.
   * <p> <p>
   * @param mapping <code>ActionMapping</code> object used to select this instance
   * @param form Optional <code>ActionForm</code> bean for this request (if any)
   * @param request <code>HttpServletRequest</code> object to process
   * @param response <code>HttpServletResponse</code> object to process
   * <p> <p>
   * @return <code>ActionForward</code> instance describing where and how
   * control should be forwarded, or null if the response has already been completed
   * <p> <p>
   * @throws Exception if an error occurs
   */
  public ActionForward processExecute(ActionMapping mapping,
                                      ActionForm form,
                                      HttpServletRequest request,
                                      HttpServletResponse response)
                               throws Exception
  {
    try {
      ViewDynaBean view = new ViewDynaBean(VIEW_BEAN_NAME, mapping);
      request.setAttribute(VIEW_BEAN_NAME, view);

     // Find the FQN for defaultCtx
      String defaultCxt = GroupContextParser.getDefaultNamingContextName();
      VisitorGroupManager vGroupMgr = new VisitorGroupManager(defaultCxt);
      VisitorGroup rootGroup = vGroupMgr.getRootVisitorGroup();
      String rootFQN = rootGroup.getFullyQualifiedName();
          
      List gDtos = new ArrayList();
      UserUtils.setP(view, "groupList", gDtos);

      String groupFQN = (String) UserUtils.getP(form, "groupFQN");
      boolean doSearch = ((Boolean) UserUtils.getP(form, "doSearch")).booleanValue();

 //   UserUtils.setP(view, "groupName", (("root".equals(groupFQN)) ?
 //		 getResources(request, "mt.messages").getMessage(getLocale(request), "mt.group.label.root") : 
 //			 extractPathName(groupFQN)));

      UserUtils.setP(view, "groupName", (("root".equals(groupFQN)) ? extractPathName(rootFQN) : extractPathName(groupFQN)));

      if (doSearch) {
        prepareGroupViewBean(groupFQN, mapping, form, view, request);
      }
    }
    catch (Exception ex) {
	ex.printStackTrace();
	return mapping.findForward("failure");
    }
    return mapping.findForward("success");
  }

  private void prepareGroupViewBean(String groupFQN,
				    ActionMapping mapping,
				    ActionForm form,
				    ViewDynaBean view,
				    HttpServletRequest request) throws Exception 
  {
    PortalVisitor agent = getPortalVisitor(request);
    Visitor visitor = agent.getVisitor();
    int serviceId = getServiceId(request);

    String searchStr = (String)UserUtils.getP(form, "searchStr");
    
    if (!UserUtils.isEmptyString(searchStr)) {
	searchStr = "%" + searchStr.trim() + "%";
    }
    else {
	searchStr = "%";
    }

    long maxNumber = ((Long) UserUtils.getP(form, "maxNumberToFind")).longValue();
    int  searchAllGroups = ((Integer) UserUtils.getP(form, "searchAllGroups")).intValue();

    VisitorGroup[] groups = null;

    if (1 == searchAllGroups) {
      if (isUserInRole(visitor, UserProfile.USER_ADMIN)) {
	groups = VisitorGroupManager.findVisitorGroupsBySubstring((int) serviceId, searchStr, (int) maxNumber);
      }
      else if (UserProfile.isOrganizationAdmin(visitor)) {
        // non user admin
	AccessManager accessMgr = AccessManager.instance();
	List orgAdmins = accessMgr.getOwnerObjectsForPrincipal((Principal)visitor, UserProfile.ORGANIZATION_ADMIN);
	if ((null != orgAdmins) && (orgAdmins.size() > 0)) {
          VisitorGroup[][] allGroups = new VisitorGroup[orgAdmins.size()][];
	  int totalLength = 0;
          for (int k = 0; k < orgAdmins.size(); k++) {
	    ACObjectID ac = (ACObjectID) orgAdmins.get(k);
            try {
	      VisitorGroup thisGroup = VisitorGroupManager.getVisitorGroupByFqn(ac.getObjectID());	    
	      allGroups[k] = thisGroup.findVisitorGroupsBySubstring(searchStr, (int)maxNumber);
              totalLength += ((null == allGroups[k]) ? 0 : allGroups[k].length);
            }
	    catch (Exception eeex) {
		// quietly return
            }
	  }
	  groups = new VisitorGroup[totalLength];
	  int i = 0;
	  for (int k = 0; k < orgAdmins.size(); k++) {
	    if (null != allGroups[k]) {
	      for (int t = 0; t < allGroups[k].length; t++) {
                groups[i++] = allGroups[k][t];
	      }
	    }
	  }
	}
      }
    }
    else {
      // search under a given group
      if ("root".equals(groupFQN)) {

	groups = VisitorGroupManager.findVisitorGroupsBySubstring((int) serviceId, searchStr, (int) maxNumber);
      }
      else if (!UserUtils.isEmptyString(groupFQN)) {
        VisitorGroup thisGroup = VisitorGroupManager.getVisitorGroupByFqn(groupFQN);
        groups = thisGroup.findVisitorGroupsBySubstring(searchStr, (int)maxNumber);
      }
      else {
	return;
      }
    }

    int numOfGroups = ((null == groups) ? 0 : groups.length);
        
    // pagination support
    
    int countOfResults = numOfGroups;
    
    // entriesPerPage is always not null
    
    int entriesPerPage = ((Integer) UserUtils.getP(form, "entriesPerPage")).intValue();
    int firstEntry = 0;
    int lastEntry = countOfResults;
    int totalPageNumber = 1;
    int currentPageNumber = 1;
    
    if (countOfResults > entriesPerPage) {
	
	// currentPageNumber and totalPageNumber are always not null
	currentPageNumber = ((Integer) UserUtils.getP(form, "currentPageNumber")).intValue();
	
	totalPageNumber = countOfResults / entriesPerPage;
	if (countOfResults % entriesPerPage > 0) {
	    totalPageNumber++;
	}
	// if the entriesPerPage has been increased
	if (currentPageNumber > totalPageNumber) {
	    currentPageNumber = totalPageNumber;
	}
	  
	if (currentPageNumber == 0) {
	    // first page
	    currentPageNumber = 1;
	}
	else {
	    firstEntry = (currentPageNumber - 1) * entriesPerPage;
	}
	lastEntry = firstEntry + entriesPerPage;
    }
    else {
	entriesPerPage = countOfResults;
    }
    
    UserUtils.setP(form, "currentPageNumber", new Integer(currentPageNumber));
    UserUtils.setP(form, "totalPageNumber", new Integer(totalPageNumber));
    
    List dtos = new ArrayList(entriesPerPage);
    UserUtils.setP(view, "groupList", dtos);
    UserUtils.setP(view, "numOfGroups", new Integer(numOfGroups));
    for (int i = firstEntry; (i < countOfResults) && (i < lastEntry); i++) {
	VisitorGroup g = groups[i];
	ViewDynaBean oneDto = new ViewDynaBean(DTO_BEAN_NAME, mapping);
	
 	UserUtils.setP(oneDto, "name", g.getFriendlyName());	
	UserUtils.setP(oneDto, "fqn", g.getFullyQualifiedName());		
	dtos.add(oneDto);

    } // end of for ... loop
  }

  private String extractPathName(String fqn) {
      int i = fqn.indexOf(":");
      if (i < 0) {
	  return fqn;
      }
      else {
	  return fqn.substring(i + 1);
      }
  }
}
